#include "StdAfx.h"

#define _USE_MATH_DEFINES
#include <math.h>

#include "ColorUtils/Color.h"
#include "ColorUtils/Image.h"

#include "FirstIntersectionResult.h"
#include "SecondIntersectionResult.h"
#include "Intersectable.h"
#include "Plain.h"
#include "FlatDisc.h"

#include "TexturedDisc.h"


TexturedDisc::TexturedDisc(const Ray& ray, double radius, const Image_ptr texturedImage) :
	FlatDisc(ray, radius, Color(0, 0, 0))
	, _image(texturedImage)
	, _radiusInv(1 / radius)
	, _radiusVec((ray.D.X != 0 || ray.D.Y != 0) ? Direction(ray.D.Y, -ray.D.X, 0): Direction(1, 0, 0))
	, _isFacingUp(abs(ray.D.Y) > 0.9)
{
	this;
}

void TexturedDisc::ColorAtIntersection(SecondIntersectionResult& result, const Point& point, const Ray&)
{
	Point directionVec = point - _center;
	double x = sqrt((directionVec).ScalarProduct(directionVec));
	double y = acos(_radiusVec.ScalarProduct(directionVec) / x);

	Point temp(directionVec.Y * _radiusVec.Z - directionVec.Z * _radiusVec.Y,
		directionVec.Z * _radiusVec.X - directionVec.X * _radiusVec.Z,
		directionVec.X * _radiusVec.Y - directionVec.Y * _radiusVec.X);
	
	if (temp.ScalarProduct(_plain.NormalAtPoint(result, point)) < 0)
		y = -y;

	y /= (2 * M_PI);
	y += 0.5;

	x *= _radiusInv;

	result.ColorAtPoint = _image->GetColor((x * _image->Width()), (y * _image->Height()));
}